package com.sfzd5.UI;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.sfzd5.aiclassroom.JsonHelper;
import com.sfzd5.aiclassroom.modle.ExamQuestionsInfo;
import com.sfzd5.aiclassroom.modle.Question;
import com.sfzd5.exam.helplibrary.Generator;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.cef.CefApp;
import org.cef.CefClient;
import org.cef.CefSettings;
import org.cef.OS;
import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.callback.CefCookieVisitor;
import org.cef.callback.CefStringVisitor;
import org.cef.handler.CefAppHandlerAdapter;
import org.cef.handler.CefLifeSpanHandlerAdapter;
import org.cef.misc.BoolRef;
import org.cef.network.CefCookie;
import org.cef.network.CefCookieManager;
import org.json.JSONObject;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import java.util.List;

public class ImportQuestionDialog extends JDialog implements WindowListener {
    private JPanel contentPane;
    private JButton bt_get_questions;
    private JButton bt_close;
    private JButton bt_get_cookies;
    private JButton bt_exam_list;
    private JPanel bpane;
    private JLabel lb_msg;
    private JButton 讲解Button;
    private JButton 选题组卷button;
    private JButton 前进Button;
    private JButton 后退Button;
    private JButton 刷新Button;

    private static final long serialVersionUID = -5570653778104813836L;
    private CefApp cefApp_;
    private CefClient client_;
    private CefBrowser browser_;
    private Component browerUI_;

    String loginUrl = "https://passport.21cnjy.com/login?jump_url=https%3A%2F%2Fzujuan.21cnjy.com%2Fu%2Fzujuan";

    StringBuilder cookieString = new StringBuilder();

    private ExamQuestionsInfo examQuestionsInfo = null;

    public ExamQuestionsInfo getExamQuestionsInfo() {
        return examQuestionsInfo;
    }

    private void initCEF(String startURL) {
        boolean useOSR = OS.isLinux();
        /*
        CefSettings settings = new CefSettings();
        settings.windowless_rendering_enabled = OS.isLinux();
        settings.persist_session_cookies = true;

        File file = new File("cache");
        if (!file.exists())
            file.mkdir();
        settings.cache_path = "cache";

        cefApp_ = CefApp.getInstance(settings);
        */
        cefApp_ = CefApp.getInstance();
        client_ = cefApp_.createClient();

        browser_ = client_.createBrowser(startURL, useOSR, false);
        browerUI_ = browser_.getUIComponent();

        client_.addLifeSpanHandler(new CefLifeSpanHandlerAdapter() {
            @Override
            public boolean onBeforePopup(CefBrowser browser, CefFrame frame, String target_url, String target_frame_name) {
                browser.loadURL(target_url);
                return true;
            }
        });

        bpane.add(browerUI_, BorderLayout.CENTER);

    }

    public ImportQuestionDialog() {
        setContentPane(contentPane);
        setModal(true);
        getRootPane().setDefaultButton(bt_get_questions);

        initCEF(loginUrl);


        this.addWindowListener((WindowListener) this);

        bt_exam_list.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                browser_.loadURL("https://zujuan.21cnjy.com/u/zujuan");
            }
        });

        bt_get_cookies.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                CefCookieManager cm = CefCookieManager.getGlobalManager();
                cm.visitAllCookies(new CefCookieVisitor() {
                    @Override
                    public boolean visit(CefCookie cc, int i, int i1, BoolRef br) {
                        System.out.println(cc.name + " = " + cc.value);
                        if (cookieString.length() > 0)
                            cookieString.append(" ");
                        cookieString.append(cc.name).append("=").append(cc.value).append(";");
                        return true;
                    }
                });
                lb_msg.setText("Cookies已获取");
            }
        });
        bt_get_questions.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                browser_.getSource(new CefStringVisitor() {
                    @Override
                    public void visit(String html) {
                        System.out.println(html);

                        String url = browser_.getURL();
                        if (!url.matches("^https://zujuan.21cnjy.com/paper/view/(\\d*)$")) {
                            lb_msg.setText("请打开组卷页面");
                            return;
                        }

                        Pattern jre = Pattern.compile("paper_detail: (.*?),\n");
                        Matcher jmc = jre.matcher(html);
                        if (jmc.find()) {
                            String paper_detail = jmc.group(1);
                            DownQuestion downQuestion = new DownQuestion(paper_detail);
                            Thread t = new Thread(downQuestion, "DownQuestion");
                            t.start();
                            lb_msg.setText("开始下载");
                        }
                    }

                });
            }
        });
        bt_close.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                onCancel();
            }
        });


        讲解Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String url = browser_.getURL();
                if (!url.matches("^https://zujuan.21cnjy.com/question/detail/(\\d*)$")) {
                    lb_msg.setText("请打开解析页面");
                    return;
                }
                browser_.getSource(new CefStringVisitor() {
                    @Override
                    public void visit(String html) {
                        int st = html.indexOf("return new Application.QuestionDetailView(") + "return new Application.QuestionDetailView(".length();
                        int ed = html.indexOf("});", st);
                        String json = html.substring(st, ed + 1);

                        st = json.indexOf("        question: ") + "        question: ".length();
                        ed = json.indexOf("\n", st);

                        json = json.substring(st, ed);

                        System.out.println(json);

                        org.json.JSONObject root = new JSONObject(json);
                        JsonHelper jsonHelper = new JsonHelper();

                        Question question = jsonHelper.toQuestion(root);

                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                QuestionInfoDialog questionInfoDialog = new QuestionInfoDialog(
                                        Generator.generateQuestionHtml_forPanelOnlyQuestion(question),
                                        0
                                );
                                questionInfoDialog.setTitle("习题讲解");
                                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                                int screenHeight = (int) screenSize.getHeight();
                                int screenWidth = (int) screenSize.getWidth();
                                Dimension d = new Dimension(screenWidth, screenHeight - 30);
                                questionInfoDialog.setSize(d);
                                questionInfoDialog.setPreferredSize(d);
                                //questionInfoDialog.setPreferredSize(new Dimension(1100, 700));
                                questionInfoDialog.pack();
                                questionInfoDialog.setVisible(true);
                            }
                        });
                    }
                });
            }
        });
        选题组卷button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                browser_.loadURL("https://zujuan.21cnjy.com/question?tree_type=knowledge&xd=2&chid=6");
            }
        });
        刷新Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                browser_.reload();
            }
        });
        后退Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(browser_.canGoBack()) browser_.goBack();
            }
        });
        前进Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(browser_.canGoForward()) browser_.goForward();
            }
        });
    }

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        contentPane = new JPanel();
        contentPane.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(2, 1, new Insets(10, 10, 10, 10), -1, -1));
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1));
        contentPane.add(panel1, new com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, 1, null, null, null, 0, false));
        final com.intellij.uiDesigner.core.Spacer spacer1 = new com.intellij.uiDesigner.core.Spacer();
        panel1.add(spacer1, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
        final JPanel panel2 = new JPanel();
        panel2.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 5, new Insets(0, 0, 0, 0), -1, -1));
        panel1.add(panel2, new com.intellij.uiDesigner.core.GridConstraints(0, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        bt_get_questions = new JButton();
        bt_get_questions.setText("获取习题");
        panel2.add(bt_get_questions, new com.intellij.uiDesigner.core.GridConstraints(0, 3, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        bt_close = new JButton();
        bt_close.setText("关闭");
        panel2.add(bt_close, new com.intellij.uiDesigner.core.GridConstraints(0, 4, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        bt_get_cookies = new JButton();
        bt_get_cookies.setText("获取Cookies");
        panel2.add(bt_get_cookies, new com.intellij.uiDesigner.core.GridConstraints(0, 2, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        bt_exam_list = new JButton();
        bt_exam_list.setText("组卷列表");
        panel2.add(bt_exam_list, new com.intellij.uiDesigner.core.GridConstraints(0, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        lb_msg = new JLabel();
        lb_msg.setText("信息");
        panel2.add(lb_msg, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        bpane = new JPanel();
        bpane.setLayout(new BorderLayout(0, 0));
        contentPane.add(bpane, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return contentPane;
    }

    class DownQuestion implements Runnable {
        OkHttpClient client;
        JsonParser parser;
        JsonObject jout;
        JsonElement root;
        int total, qi;

        public DownQuestion(String paper_detail) {
            client = new OkHttpClient.Builder()
                    .retryOnConnectionFailure(true)
                    .connectTimeout(60, TimeUnit.SECONDS) //连接超时
                    .readTimeout(300, TimeUnit.SECONDS) //读取超时
                    .writeTimeout(600, TimeUnit.SECONDS) //写超时
                    .build();

            parser = new JsonParser();
            jout = new JsonObject();
            this.root = parser.parseString(paper_detail);
            ;
        }

        @Override
        public void run() {
            JsonObject j = root.getAsJsonObject();
            JsonObject _meta = j.getAsJsonObject("_meta");

            total = _meta.get("question_num").getAsInt();
            qi = 0;

            jout.add("xd", _meta.get("xd"));
            jout.add("chid", _meta.get("chid"));
            jout.add("pid", _meta.get("pid"));
            jout.add("title", _meta.get("title"));
            jout.add("subtitle", _meta.get("subtitle"));
            jout.add("question_num", _meta.get("question_num"));

            JsonArray qs = new JsonArray();

            JsonArray content = j.getAsJsonArray("content");

            for (JsonElement ge : content) {
                JsonObject g = ge.getAsJsonObject();
                //https://zujuan.21cnjy.com/question/detail/20774007

                //JEnumerable<JToken> jqs = q["questions"].Children();

                JsonObject nq = new JsonObject();
                nq.add("head_title", g.get("head_title"));

                JsonArray nqs = new JsonArray();
                JsonArray questions = g.getAsJsonArray("questions");
                for (JsonElement qe : questions) {
                    JsonObject qc = qe.getAsJsonObject();
                    int question_id = qc.get("question_id").getAsInt();
                    String json = downQuestionJson(question_id);
                    nqs.add(parser.parseString(json));

                    qi++;
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            lb_msg.setText(qi + "/" + total);
                        }
                    });
                }
                nq.add("questions", nqs);
                qs.add(nq);


            }
            jout.add("content", qs);

            JsonHelper helper = new JsonHelper(jout.toString());
            ImportQuestionDialog.this.examQuestionsInfo = helper.toExamQuestionsInfo();
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    lb_msg.setText("下载完成");
                    ImportQuestionDialog.this.onCancel();
                }
            });
        }

        String downQuestionJson(int question_id) {
            //可以直接获取json，里面包含答案图片和解析图片地址，但不包含文本答案部分
            //https://zujuan.21cnjy.com/api/question/question-detail-access?qid=46755171&_=1616216177854
            //{"code":0,"msg":"success","data":{"access":true,"explain_sort_need":0,"sub_explanation":null,"answer":"http://webshot.21cnjy.com/q/1a/86/52ad8c4846541967bd2a79203001_46757975an.png?hash=16b1de2b0d8958a50e7582aab328fcb5&sign=7a505824e2b67ba34d710c58ba1c2fb2&sort=0&parent_id=0","explanation":"http://webshot.21cnjy.com/q/1a/86/52ad8c4846541967bd2a79203001_46757975ex.png?hash=a62de5b29a548bbd425a2c1022555e9e&sign=a5bd91fe496eca45f52ecffa3d04028b&sort=0&parent_id=0","list":null},"_timestamp":null,"action":"question-detail-access"}
            String url = "https://zujuan.21cnjy.com/question/detail/" + question_id;
            Request request = new Request.Builder()
                    .url(url)
                    .header("Cookie", cookieString.toString())
                    .build();
            Call call = client.newCall(request);
            try {
                Response response = call.execute();

                String html = response.body().string();
                int st = html.indexOf("return new Application.QuestionDetailView(") + "return new Application.QuestionDetailView(".length();
                int ed = html.indexOf("});", st);
                String json = html.substring(st, ed + 1);
                return json;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }


    private void onCancel() {
        // add your code here if necessary
        // CefApp.getInstance().dispose();
        dispose();
    }

    @Override
    public void windowOpened(WindowEvent e) {

    }

    @Override
    public void windowClosing(WindowEvent e) {
        onCancel();
    }

    @Override
    public void windowClosed(WindowEvent e) {

    }

    @Override
    public void windowIconified(WindowEvent e) {

    }

    @Override
    public void windowDeiconified(WindowEvent e) {

    }

    @Override
    public void windowActivated(WindowEvent e) {

    }

    @Override
    public void windowDeactivated(WindowEvent e) {

    }
}
